package ce.com.cenewbluesdk.queue;

import android.util.Log;

import ce.com.cenewbluesdk.CEBC;
import ce.com.cenewbluesdk.entity.CEDevData;
import ce.com.cenewbluesdk.entity.QueueSendData;

/**
 * Created by Administrator on 2016/11/9 0009.
 */
public class CEProtocolA extends CEProtocolBase {
    private int devType;

    public CEProtocolA(int devType) {
        this.devType = devType;
    }

    @Override
    public QueueSendData getSendData(CEDevData devData) {

        byte[] frameBytes  = new byte[20];
        int offset = 0;
        frameBytes[offset++] = (byte)devType;
        frameBytes[offset++] = (byte)devData.getCmd();
        frameBytes[offset++] = (byte)devData.getDataType();
        int tDataLen=0;
        if(devData.getData()!=null){
            tDataLen = devData.getData().length;
        }
        int tIndexLocation = tDataLen / 16;
        if (tDataLen % 16 != 0){
            ++tIndexLocation;
        }

        if (devData.getCmd() == CEBC.CMD_APP_ACK_TYPE){
            tIndexLocation = 0;
            devData.setTotalIndex(tIndexLocation);
        }
        else {
            devData.setTotalIndex(tIndexLocation);
        }


        tIndexLocation = (tIndexLocation << 4);
        tIndexLocation |= (devData.getCurrentIndex() & 0x000f);

        frameBytes[offset++] = (byte)tIndexLocation;

        QueueSendData tSendData = new QueueSendData();
        if (devData.getCmd() == CEBC.CMD_REQUEST_TYPE){

        }
        else if (devData.getCmd() == CEBC.CMD_SEND_TYPE){
            if (devData.getCurrentIndex() == 0) {
                frameBytes[offset++] = (byte) devData.getItemNumber();
                frameBytes[offset++] = (byte) devData.getItemL();
                int tCrcSum = devData.figureCrc16();
                frameBytes[offset++] = (byte) (tCrcSum & 0xff);
                frameBytes[offset++] = (byte) (tCrcSum >> 8);
                if(devData.getOtherData()!=null){
                    int otherL=devData.getOtherData().length>12?12:devData.getOtherData().length;
                    System.arraycopy(devData.getOtherData(), 0, frameBytes, 8, otherL);
                }
            }
            else {
                int tLen = 16;
                if (devData.getCurrentIndex()*16  > devData.getData().length){
                    tLen = devData.getData().length -( devData.getCurrentIndex()-1)*16;
                }

                System.arraycopy(devData.getData(), (devData.getCurrentIndex()-1)*16, frameBytes, offset, tLen);
            }
        }
        else if (devData.getCmd() == CEBC.CMD_APP_ACK_TYPE){
            frameBytes[1] = (byte)CEBC.CMD_ACK_TYPE;
            tSendData.setIndex(5);
        }
        tSendData.setSendData(frameBytes);

        return tSendData;
    }

    @Override
    public CEDevData Analysis(byte[] bytes) {

        if (bytes.length < 20){

        }

        int tPid = bytes[0];
        int tCmdType = bytes[1];
        int tDataType = bytes[2];
        int tIndexLocation = bytes[3]&0xff;


        int tCurrentIndex = (tIndexLocation & 0x0f);

        int tTotalIndex = (tIndexLocation >> 4);


        Log.e("CE_blue", "tCurrentIndex: "+tCurrentIndex + " tTotalIndex: " + tTotalIndex);

        CEDevData tDevData = dataHashMap.get(tDataType);
        if (tDevData == null){
            tDevData = new CEDevData();
            tDevData.setCmd(tCmdType);
            tDevData.setDataType(tDataType);
            tDevData.setCurrentIndex(tCurrentIndex);
            tDevData.setTotalIndex(tTotalIndex);

            dataHashMap.put(tDataType, tDevData);
        }

        if (tCurrentIndex == 0){ // 头包
            //

            tDevData.setData(new byte[0]);

            int tItemNum = bytes[4];
            int tItemSize = bytes[5];
            tDevData.setItemNumber(tItemNum);
            tDevData.setItemL(tItemSize);

            int tData_crc16 = 0;
            tData_crc16 |= (bytes[7] & 0x00ff);
            tData_crc16 <<= 8;
            tData_crc16 |= (bytes[6] & 0x00ff);
            tDevData.setDataCrc16(tData_crc16);

            if (tTotalIndex > 0){
                return null;
            }
        }

        if (tCurrentIndex <= tTotalIndex){ //接收数据

            if (tTotalIndex == 0){

                if (tCmdType != CEBC.CMD_ACK_TYPE){
                    tDevData.setCmd(CEBC.CMD_APP_ACK_TYPE); // 需要app回复ack
                }else {
                    tDevData.setCmd( CEBC.AckApp.CMD_ACK); // 需要app回复ack
                    tDevData.setData(convertACK(bytes[8]));
                }
                removeMapData(tDataType);
                return tDevData;
            }

            byte[] new_payload = new byte[240];
            int offset = 0;
            if (tDevData.getData().length > 0){
                System.arraycopy(tDevData.getData(), 0, new_payload, offset, tDevData.getData().length);
                offset += tDevData.getData().length;
            }
            System.arraycopy(bytes, 4, new_payload, offset, 16);
            offset += 16;

            byte[] turePayLoad = new byte[offset];
            System.arraycopy(new_payload, 0, turePayLoad, 0, offset);

            tDevData.setData(turePayLoad);

            if (tCurrentIndex == tTotalIndex){
                if (tCmdType != CEBC.CMD_ACK_TYPE){
                    tDevData.setCmd(CEBC.CMD_APP_ACK_TYPE); // 需要app回复ack
                }
                removeMapData(tDataType);
                return tDevData;
            }
        }

        return null;
    }

    @Override
    public void removeMapData(Integer dateTypeKey) {
        dataHashMap.remove(dateTypeKey);
    }

    @Override
    public  byte[] convertACK(byte ack) {

        byte appAck=CEBC.AckApp.ACK_TYPE_NULL;
        switch (ack){
            case 0:
                appAck=CEBC.AckApp.ACK_TYPE_SUCCESS;
                break;
            case 2:
                appAck=CEBC.AckApp.ACK_TYPE_WRONG;
                break;
            case 3:
                appAck=CEBC.AckApp.ACK_TYPE_CRC16_WRONG;
                break;
            case 4:
                appAck=CEBC.AckApp.ACK_TYPE_OVER;
                break;
        }
        return new byte[]{appAck};
    }


}
